package cn.itsource.org.service.impl;

import cn.hutool.Hutool;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import cn.itsource.basic.service.BaseServiceImpl;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.RedisService;
import cn.itsource.basic.util.SendMessageService;
import cn.itsource.config.exception.CustomException;
import cn.itsource.org.Dto.LoginDto;
import cn.itsource.org.Vo.LoginVo;
import cn.itsource.org.domain.User;
import cn.itsource.org.mapper.UserMapper;
import cn.itsource.org.query.UserQuery;
import cn.itsource.org.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

@Service
public class UserServiceImpl extends BaseServiceImpl<User, UserQuery> implements IUserService {
    @Autowired
    private UserMapper mapper;
    @Autowired
    private RedisService redisService;
//发送短信
    @Override
    public AjaxResult sendmobilecode(String phone, HttpServletRequest request) {
        //拦截同一个ip一直获取验证码  //
        String s = request.getRemoteAddr() + request.getRequestURI();
        int i = s.lastIndexOf("/");
        String ipPhoneStr = s.substring(0, i);
        String res = redisService.getKeyObjectValue(ipPhoneStr, String.class);
        if (res != null){ //如果redis里面有数据，代表你访问过于频繁
            throw new CustomException("哥哥，你太快了...");
        }
        //存ip到redis中,保持1分钟,1分钟内重复获取抛出上面的异常
        redisService.setStringKeyAndValue(ipPhoneStr,phone,1);

        String yzm = RandomUtil.randomNumbers(4);
        redisService.setStringKeyAndValue(phone,yzm,10);
        SendMessageService.sendPhoneMessage(phone,redisService.getKeyStringValue(phone));
        return AjaxResult.createSuccess();
    }

    @Override
    public AjaxResult checkphone(String phone) {
        //验证手机号(工具类)
        boolean mobile = Validator.isMobile(phone);
        if (!mobile){
            throw new CustomException("手机号有误,请重新输入...");
        }
        User checkphone = mapper.checkphone(phone);
        if (checkphone!=null){
            //todo  已经注册过,无需注册
            throw new RuntimeException("该手机号已被注册!");
        }else {
            //todo 未注册,可以注册
            return AjaxResult.createSuccess("已通过验证");

        }
    }
// 注册接口
    @Override
    public void register(User user) {
//        判断验证码是否一致
        if (!StrUtil.equals(user.getCode(),redisService.getKeyStringValue(user.getPhone()))){
            throw new CustomException("驗證碼錯誤！");
        }
        if (StrUtil.isBlank(redisService.getKeyStringValue(user.getPhone()))){
            throw new CustomException("验证码已失效！");
        }
        //        验证两次密码是否一致
        if (!StrUtil.equals(user.getPassword(),user.getConfirmPassword())){
            throw new CustomException("两次密码不一致!");
        }
        /**
         * 加盐加密流程
         */
//        用uuid生成盐值
        String simpleUUID = IdUtil.fastSimpleUUID();
//        密码加盐基础上进行---Md5加密
        String pwd = MD5.create().setSalt(simpleUUID.getBytes()).digestHex(user.getConfirmPassword());
//        入库
        user.setSalt(simpleUUID);
        user.setPassword(pwd);
        mapper.insertSelective(user);
    }

    @Override
    public AjaxResult login(LoginDto loginDto) {
        //1.去t_user表匹配账户
        User dbUser = mapper.findByUsername(loginDto);

        //2.如果user不存在，返回提示
        if (dbUser == null){
            throw new CustomException("账户密码不匹配");
        }

        //4.如果匹配到了，对进来的密码串加盐加密和数据库的加密串进行比对，
        //4.1拿到数据库的盐值，再对页面传递过来的密码进行加密
        String pageMd5Pwd = MD5.create().setSalt(dbUser.getSalt().getBytes()).digestHex(loginDto.getPassword());

        //5.比对不过，返回错误  pageMd5Pwd:页面密码加密串   dbEmployee.getPassword():数据库的加密串
        if (!StrUtil.equals(pageMd5Pwd,dbUser.getPassword())){
            throw new CustomException("账户名与密码不匹配，请重新输入");
        }
        //6.成功，存放redis.setKv(token,用户信息，时间)
        String token = IdUtil.fastSimpleUUID();
        //6.1封装成一个通用对象，用户系统和后台系统都可以用这个
        LoginVo loginVo = BeanUtil.copyProperties(dbUser, LoginVo.class);
        loginVo.setToken(token);

        redisService.setStringKeyAndValue(token,loginVo,30);
        //7.返回vo对象，vo专门用来返回值给前端页面的
        return AjaxResult.createSuccess(loginVo);

    }
}
